package com.zzg.mybatis.generator.controller;

import com.zzg.mybatis.generator.model.DatabaseConfig;
import com.zzg.mybatis.generator.model.GeneratorConfig;
import com.zzg.mybatis.generator.util.ConfigHelper;
import com.zzg.mybatis.generator.util.IDCellUtil;
import com.zzg.mybatis.generator.util.StringUtil;
import com.zzg.mybatis.generator.view.AlertUtil;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.TextInputDialog;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.stage.DirectoryChooser;
import javafx.util.StringConverter;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;

/**
 * 管理GeneratorConfig的Controller
 *
 * Created by Owen on 8/21/16.
 */
public class GeneratorConfigController extends BaseFXController {

    private static final Logger _LOG = LoggerFactory.getLogger(GeneratorConfigController.class);

    @FXML
    private ComboBox<DatabaseConfig> dbsChoice;
    @FXML
    private TableView<GeneratorConfig> configTable;
    @FXML
    private TableColumn<?,?> indexColumn;
    @FXML
    private TableColumn<?,?> nameColumn;
    @FXML
    private TableColumn<?,?> opsColumn;
    //右侧配置文本域
    @FXML
    private TextField idField; //配置表编号
    @FXML
    private TextField nameField; //配置名称
    @FXML
    private TextField projectFolderField;
    @FXML
    private TextField generateKeysField;	//主键ID
    @FXML
    private TextField modelTargetPackage;
    @FXML
    private TextField modelTargetProject;
    @FXML
    private TextField daoTargetPackage;
    @FXML
    private TextField daoTargetProject;
    @FXML
    private TextField mapperTargetPackage;
    @FXML
    private TextField mappingTargetProject;

    private MainUIController mainUIController;

    private GeneratorConfigController controller;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        controller = this;
        configTable.setRowFactory(tv -> {
            TableRow<GeneratorConfig> row = new TableRow<>();
            row.setOnMouseClicked(event -> {
                if(event.getClickCount() == 1 && (! row.isEmpty())){
                	setGeneratorConfigIntoUI(row.getItem());
                }
            });
            return row;
        });
        indexColumn.setCellFactory(new IDCellUtil<>()); //自增序号
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
        opsColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
        // 自定义操作列
        opsColumn.setCellFactory(cell -> {
            return new TableCell<Object,Object>(){
                @Override
                protected void updateItem(Object item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item == null || empty) {
                        setText(null);
                        setGraphic(null);
                    } else {
                        Button btn1 = new Button("应用");
                        Button btn2 = new Button("删除");
                        HBox hBox = new HBox();
                        hBox.setSpacing(10);
                        hBox.getChildren().add(btn1);
                        hBox.getChildren().add(btn2);
                        btn1.setOnAction(event -> {
                            try {
                                // 应用配置
                                List<GeneratorConfig> genconfigList = ConfigHelper.queryGeneratorConfig(item.toString(),1);
                                if(genconfigList != null && genconfigList.size()>0){
                                	mainUIController.setGeneratorConfigIntoUI(genconfigList.get(0));
                                    controller.closeDialogStage();
                                }else{
                                	AlertUtil.showErrorAlert("配置为空！");
                                }
                            } catch (Exception e) {
                                AlertUtil.showErrorAlert(e.getMessage());
                            }
                        });
                        btn2.setOnAction(event -> {
                            try {
                                // 删除配置
                                _LOG.debug("item: {}", item);
                                ConfigHelper.deleteGeneratorConfig(item.toString());
                                refreshTableView("",1);
                            } catch (Exception e) {
                                AlertUtil.showErrorAlert(e.getMessage());
                            }
                        });
                        setGraphic(hBox);
                    }
                }
            };
        });
        try{
        	List<DatabaseConfig> dbsList = ConfigHelper.loadDatabaseConfig();
        	dbsChoice.setItems(FXCollections.observableList(dbsList));
        }catch(Exception e){
        	AlertUtil.showErrorAlert(e.getMessage());
        }
        dbsChoice.setConverter(new StringConverter<DatabaseConfig>(){
			@Override
			public String toString(DatabaseConfig obj){
				return obj.getName();
			}
			@Override
			public DatabaseConfig fromString(String obj){
				return null;
			}
		});
        //设置被选中事件
        dbsChoice.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<DatabaseConfig>(){
			@Override
			public void changed(ObservableValue<? extends DatabaseConfig> observable,DatabaseConfig oldValue,DatabaseConfig newValue){
				refreshTableView("",newValue.getId());
			}
        });
        //默认选中第一个
        dbsChoice.getSelectionModel().selectFirst();
        refreshTableView("",1);
    }
    
    @FXML
    public void chooseProjectFolder() {
        DirectoryChooser directoryChooser = new DirectoryChooser();
        File selectedFolder = directoryChooser.showDialog(getPrimaryStage());
        if (selectedFolder != null) {
            projectFolderField.setText(selectedFolder.getAbsolutePath());
        }
    }
    
    @FXML
    public void addGeneratorConfig(){
    	//新增时，清空配置表单文本域
    	setGeneratorConfigIntoUI(new GeneratorConfig());
    }
    
    @FXML
    public void saveGeneratorConfig(){
    	GeneratorConfig generatorConfig = getGeneratorConfigFromUI();
    	Integer id = generatorConfig.getId();
    	String name = generatorConfig.getName();
    	DatabaseConfig databaseConfig = dbsChoice.getSelectionModel().getSelectedItem();
    	Integer p_id = databaseConfig.getId();
    	if(id == null){
    		if("".equals(StringUtil.priseString(p_id))){
    			AlertUtil.showErrorAlert("请先选择数据库！");
    			return;
    		}else{
    			generatorConfig.setP_id(p_id);
    		}
    	}
    	if("".equals(StringUtil.priseString(name)) && id == null){
    		TextInputDialog dialog = new TextInputDialog("");
        	dialog.setTitle("保存当前配置");
        	dialog.setContentText("请输入配置名称");
        	Optional<String> result = dialog.showAndWait();
        	if(result.isPresent()){
        		if(StringUtils.isEmpty(result.get())){
        			AlertUtil.showErrorAlert("名称不能为空");
        			return;
        		}else{
        			generatorConfig.setName(name);
        			_LOG.info("user choose name: {}", name);
        		}
        	}else{
        		return;
        	}
    	}
    	try{
			String encoding = generatorConfig.getEncoding();
			if("".equals(StringUtil.priseString(encoding))){
				generatorConfig.setEncoding("UTF-8");
			}
			ConfigHelper.saveGeneratorConfig(generatorConfig);
			refreshTableView("",1);
		}catch(Exception e){
			AlertUtil.showErrorAlert("保存配置失败！");
		}
    }
    
    public GeneratorConfig getGeneratorConfigFromUI() {
        GeneratorConfig generatorConfig = new GeneratorConfig();
        if(!"".equals(StringUtil.priseString(idField.getText()))){
        	generatorConfig.setId(Integer.parseInt(idField.getText()));
        }
        generatorConfig.setName(nameField.getText());
        generatorConfig.setProjectFolder(projectFolderField.getText());
        generatorConfig.setGenerateKeys(generateKeysField.getText());
        generatorConfig.setModelPackage(modelTargetPackage.getText());
        generatorConfig.setModelPackageTargetFolder(modelTargetProject.getText());
        generatorConfig.setDaoPackage(daoTargetPackage.getText());
        generatorConfig.setDaoTargetFolder(daoTargetProject.getText());
        generatorConfig.setMappingXMLPackage(mapperTargetPackage.getText());
        generatorConfig.setMappingXMLTargetFolder(mappingTargetProject.getText());
        return generatorConfig;
    }
    
    public void setGeneratorConfigIntoUI(GeneratorConfig generatorConfig){
    	idField.setText(StringUtil.priseString(generatorConfig.getId()));
    	nameField.setText(generatorConfig.getName());
        projectFolderField.setText(generatorConfig.getProjectFolder());
        generateKeysField.setText(generatorConfig.getGenerateKeys());
        modelTargetPackage.setText(generatorConfig.getModelPackage());
        modelTargetProject.setText(generatorConfig.getModelPackageTargetFolder());
        daoTargetPackage.setText(generatorConfig.getDaoPackage());
        daoTargetProject.setText(generatorConfig.getDaoTargetFolder());
        mapperTargetPackage.setText(generatorConfig.getMappingXMLPackage());
        mappingTargetProject.setText(generatorConfig.getMappingXMLTargetFolder());
    }

    public void refreshTableView(String name,Integer p_id){
        try{
        	List<GeneratorConfig> configs = ConfigHelper.queryGeneratorConfig(name,p_id);
            configTable.setItems(FXCollections.observableList(configs));
            //清空配置表单
            setGeneratorConfigIntoUI(new GeneratorConfig());
        }catch (Exception e){
            AlertUtil.showErrorAlert(e.getMessage());
        }
    }
    
    void setMainUIController(MainUIController mainUIController) {
        this.mainUIController = mainUIController;
    }
}